package com.example.zookeeper.lock.watch;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;


/**
 * @author Vicente
 * @version 1.0
 * @date 2020/3/9 15:24
 */
public class WatchCallBack implements Watcher, AsyncCallback.StringCallback, AsyncCallback.Children2Callback, AsyncCallback.StatCallback {
    private static Logger logger = LoggerFactory.getLogger(WatchCallBack.class);

    private ZooKeeper zooKeeper;
    private CountDownLatch latch = new CountDownLatch(1);
    private String threadName;
    private String pathName;



    public void setZooKeeper(ZooKeeper zooKeeper) {
        this.zooKeeper = zooKeeper;
    }

    public void setThreadName(String threadName) {
        this.threadName = threadName;
    }

    public void tryLock(){
        zooKeeper.create("/lock",
                threadName.getBytes(),
                ZooDefs.Ids.OPEN_ACL_UNSAFE,
                CreateMode.EPHEMERAL_SEQUENTIAL,
                this,
                "A");
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void unLock(){
        try {
            zooKeeper.delete(pathName,-1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }
    }

    public void process(WatchedEvent watchedEvent) {
        switch (watchedEvent.getType()) {
            case None:
                break;
            case NodeCreated:
                break;
            case NodeDeleted:
                zooKeeper.getChildren("/",false,this,"E");
                break;
            case NodeDataChanged:
                break;
            case NodeChildrenChanged:
                break;
            case DataWatchRemoved:
                break;
            case ChildWatchRemoved:
                break;
        }
    }

    public void processResult(int i, String s, Object o, String s1) {
        if(s1 != null){
            pathName = s1;
            logger.warn("创建节点--"+s1);
            zooKeeper.getChildren("/",false,this,"B");
        }
    }

    public void processResult(int i, String s, Object o, List<String> list, Stat stat) {
        //并发情况下，创建节点成功
        Collections.sort(list);
        int index = list.indexOf(pathName.substring(1));
        if(index == 0){
            logger.warn("当前节点："+pathName + "- I'm the first");
            try {
                zooKeeper.setData("/",threadName.getBytes(),-1);
                latch.countDown();
            } catch (KeeperException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else{
            zooKeeper.exists("/"+list.get(index-1),this,this,"C");
        }
    }

    public void processResult(int i, String s, Object o, Stat stat) {

    }
}
